'''
Created on Oct 21, 2009

@author: mkiyer
'''

import os
import sys
import collections
import glob
import logging
from optparse import OptionParser
from bx.intervals.intersection import Interval, IntervalTree
from veggie.io.bed import bed_reader
from veggie.sample.sampledb2 import get_sampledb
from veggie.sample.samplegroup import parse_samplegroups_xml

if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)
    outfhd = sys.stdout
    results_suffix = "unknown_candidates.bed"
    qc_fail_libraries = set(['30WU2AAXX_2',
                             '30WU2AAXX_3',
                             '42P6UAAXX_8'])

    # parse command line
    optionparser = OptionParser("usage: %prog [options] <sample_xml_file> <bed_dir>")
    (options, args) = optionparser.parse_args()    
    sample_groups = list(parse_samplegroups_xml(args[0]))
    samples = set([])
    for sgroup in sample_groups:
        samples.update(sgroup.samples)
    results_path = args[1]

    trees = collections.defaultdict(lambda: IntervalTree())
    intervals = []
    libraries = []
    library_samples = {}
    sample_libraries = collections.defaultdict(lambda: [])
    
    for sample in samples:
        for res in get_sampledb().params[sample]['lanes']:
            flowcell, lane = res
            library_id = '%s_%d' % (flowcell, lane)
            library_bedfile = '%s.%s' % (library_id, results_suffix)
            library_path = os.path.join(results_path, library_bedfile)
            if not os.path.exists(library_path):
                logging.critical('File not found: %s' % library_path)
            if library_id in qc_fail_libraries:
                logging.debug('Skipping poor quality library %s' % (library_id))
                continue
            logging.debug('Adding library %s to sample %s' % (library_id, sample))
            libraries.append(library_id)
            library_samples[library_id] = sample
            sample_libraries[sample].append(library_id)
            for annot in bed_reader(open(library_path)):
                # add sample attribute
                annot.sample = sample
                trees[annot.chrom].insert_interval(Interval(annot.start, annot.end, value=annot))
                intervals.append(annot)

    # print header
    sorted_samples = sorted(sample_libraries.keys())
    outfhd.write('Sample')
    for sample in sorted_samples:
        for library in sample_libraries[sample]:
            outfhd.write('\t%s' % sample)
    outfhd.write('\n')
    # write all properties in param_schema
    for prop in sorted(get_sampledb().param_schema.keys()):
        outfhd.write('%s' % prop)
        for sample in sorted_samples:
            for library in sample_libraries[sample]:
                if prop in get_sampledb().params[sample]:
                    outfhd.write('\t%s' % get_sampledb().params[sample][prop])
                else:
                    outfhd.write('\tNone')
        outfhd.write('\n')
    outfhd.write('Library')
    for sample in sorted_samples:
        for library in sample_libraries[sample]:
            outfhd.write('\t%s' % library)
    outfhd.write('\n')
    
    # intersect each interval
    for interval in intervals:
        hits = trees[interval.chrom].find(interval.start, interval.end)

        library_hits = collections.defaultdict(lambda: [])
        for hit in hits:
            annot = hit.value
            library_hits[annot.name.split('.')[0]].append(annot.score)

        outfhd.write('%s:%d-%d' % (interval.chrom, interval.start, interval.end))        
        for sample in sorted_samples:
            for library in sample_libraries[sample]:
                if library in library_hits:
                    outfhd.write('\t%s' % (','.join(map(str,library_hits[library]))))
                else:
                    outfhd.write('\t0.0')
        outfhd.write('\n')

